package com.loveyukari.service;

import com.loveyukari.common.Pager;
import com.loveyukari.common.exception.InternalException;
import com.loveyukari.dao.BanAuthDao;
import com.loveyukari.model.Auth;
import com.loveyukari.model.BanAuth;
import com.loveyukari.utils.HttpUtils;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.cxf.transport.http.Headers;
import org.apache.http.Header;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

@Service
public class BanService {


    private Logger logger = LoggerFactory.getLogger(BanService.class);

    @Autowired
    private AuthService authService;
    @Autowired
    private BanAuthDao banAuthDao;



    @Scheduled(cron = "0 0 3 * * *")
    public void autoBanAuth(){
        List<BanAuth> list = banAuthDao.selectAutoShutUp();
        for (BanAuth banAuth :
                list) {
            if (banAuth.getEndTime().getTime() - System.currentTimeMillis() < 259200000){
                try {
                    banAccount(banAuth.getAuthId(),banAuth.getExecutor(),43200,"自动禁言-循环");
                    Thread.sleep(500);
                } catch (Exception e) {
                    logger.error("auto ban auth error: "+e.getMessage(),e);
                }
            }
        }
    }

    @Scheduled(cron = "30 0/5 * * * *")
    public void autoExpire(){
        banAuthDao.updateBanAuthAutoExpire();
    }

    public List<BanAuth> getBanAuthList(Pager pager){
        List<BanAuth> list = banAuthDao.selectShutUpList(pager);
        for (BanAuth banAuth:
             list) {
            Auth auth = authService.getCacheAuth(banAuth.getAuthId());
            Auth executor = authService.getCacheAuth(banAuth.getExecutor());
            banAuth.setAuthName(auth.getName());
            banAuth.setExecutorName(executor.getName());
        }
        pager.setTotal(banAuthDao.countShutUp());
        return list;
    }

    public void saveBanAccount(int authId,int executor,Date endTime,String message){
        BanAuth banAuth = banAuthDao.selectShutUp(authId);
        int autoStatus = 0;
        if (banAuth != null){
            autoStatus = banAuth.getAutoStatus();;
            banAuthDao.updateLoseAuth(authId);
        }
        JSONObject chatmsgJson = authService.getAuthLastTalk(authId);
        String chatmsg = "";
        if (chatmsgJson != null){
            chatmsg = chatmsgJson.optString("txt","");
        }
        Date startTime = new Date();
        banAuth = new BanAuth();
        banAuth.setChatmsg(chatmsg);
        banAuth.setAutoStatus(autoStatus);
        banAuth.setExecutor(executor);
        banAuth.setStartTime(startTime);
        banAuth.setEndTime(endTime);
        banAuth.setMessage(message);
        banAuth.setStatus(1);
        banAuth.setAuthId(authId);
        banAuthDao.insertBanAuth(banAuth);
    }



    public void updateAccountAutoShutUp(int id,int executor) {
        BanAuth banAuth = banAuthDao.selectById(id);
        if (banAuth.getExecutor() != executor){
            banAuth.setExecutor(executor);
            banAuth.setAutoStatus(banAuth.getAutoStatus() == 0 ? 1 : 0);
            banAuthDao.updateLoseAuth(banAuth.getAuthId());
            banAuthDao.insertBanAuth(banAuth);
        } else {
            banAuthDao.updateBanAuthAutoStatus(banAuth.getId(),banAuth.getAutoStatus() == 0 ? 1 : 0);
        }

    }


    public void banAccount(String authName,int executor,int time,String message) throws Exception {
        Auth auth = authService.findAuthByName(authName);
        if (auth != null){
            banAccount(auth,executor,time,message);
        } else {
            throw new InternalException("id不存在");
        }
    }

    public void banAccount(int authId,int executor,int time,String message) throws Exception {
        Auth auth = authService.getCacheAuth(authId);
        if (auth != null){
            banAccount(auth,executor,time,message);
        }
    }

    public void removeAccount(int authId) throws Exception {
        BanAuth banAuth = banAuthDao.selectShutUp(authId);
        if (banAuth == null){
            return;
        }
        HashMap<String, Object> params = new HashMap<>();
        params.put("uid",banAuth.getAuthId());
        params.put("room_id",196);
        String url = "https://www.douyu.com/room/roomSetting/deleteMuteUser";
        banAccount(url,params,true);
        banAuthDao.updateBanAuthExpire(banAuth.getId());
    }

    private void banAccount(Auth auth,int executor,int time,String message) throws Exception {
        if (StringUtils.isBlank(message)){
            throw new InternalException("禁言理由不能为空");
        }
        saveBanAccount(auth.getId(),executor,DateUtils.addMinutes(new Date(),time),message);
        HashMap<String, Object> params = new HashMap<>();
        params.put("ban_nickname",auth.getName());
        params.put("room_id",196);
        params.put("ban_time",time);
        String url = "https://www.douyu.com/room/roomSetting/addMuteUser";
        banAccount(url,params,true);
    }


    private Map<String,String> cookiesMap = new HashMap<>();
    private void banAccount(String url,Map<String,Object> params,boolean initFlag) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        Set<String> keys = params.keySet();
        for (String key :
                keys) {
            Object o = params.get(key);
            nameValuePairs.add(new BasicNameValuePair(key, String.valueOf(o)));
        }
        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
        httpPost.setHeader("Referer","https://www.douyu.com/room/roomSetting/getMuteList/196");
        StringBuilder cookiesSb = new StringBuilder();
        if (cookiesMap != null){
            Set<String> names = cookiesMap.keySet();
            for (String name :
                    names) {
                String value = cookiesMap.get(name);
                cookiesSb.append(name).append("=").append(value).append(";");
            }
        }
        httpPost.setHeader("Cookie",cookiesSb.toString());
        CloseableHttpClient httpClient = HttpUtils.getHttpClient();
        CloseableHttpResponse response = httpClient.execute(httpPost);
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200){
            String result = EntityUtils.toString(response.getEntity());
            JSONObject resultJson = JSONObject.fromObject(result);
            if (resultJson.optInt("error") == 1){
                JSONObject logJson = JSONObject.fromObject(params);
                logJson.put("url",url);
                logger.info("ban account success: "+logJson.toString());
            } else {
               throw new InternalException(resultJson.optString("msg"));
            }
        } else if (statusCode == 302 && initFlag){
            initCookiesMap();
            banAccount(url,params,false);
        } else {
            logger.error("Cookie error!!!!");
        }

    }


    private String xiaoyuanLTP0 = "2673484LzL6A5zwLOB6qDwwpYM50g7rToxiGbX7vEQxmRP41XEBwpqLLkhjcZ5b0c8CiU9nV%2FOHfzm%2FooeUh3gdwbd%2BEIM1%2F2UIKrVdeFXkkBTTwWwrMwkhoG06raJEtneW%2FpjjvJKlMjcGBd8mAYvzG5rTva1RWr2%2B1MBpDg%2FLVeKCFJDN%2FZGa6dT4sFATVo";

    public void initCookiesMap() throws Exception {
        CloseableHttpClient httpClient = HttpUtils.getHttpClient();
        HttpPost post = new HttpPost("https://passport.douyu.com/member/login");
//        post.setHeader("Cookie","LTP0="+xiaoyuanLTP0);
        post.setHeader("Cookie","LTP0=fac017UXSIqE6vmZI39UUbaFSrs%2BYSl09wiUMAvtfIbe6awd01amZ0AgeG8sg116prSZr%2BcFwNsyA6hvkKDkadRMbhKgrJcTkhmVFxkA%2FSoRZqmgraNqIvo0xtzHkTd7M5yEEAQ8dhukfwqaGixnav6KJXav44eEyGiMeadRN5cKxOI7mytzHx6cmqcm2H4MenTTOP5A;");
//            post.setHeader("Referer","https://www.douyu.com/room/roomSetting/getMuteList/196");
        CloseableHttpResponse   response = httpClient.execute(post);//
        if (response.getStatusLine().getStatusCode() == 302){
            Header header = response.getFirstHeader("Location");
            String uri = header.getValue();
            post = new HttpPost("https:"+uri);
            response = httpClient.execute(post);//
            Header[] headers = response.getHeaders("Set-Cookie");
            cookiesMap = new HashMap<>();
            for (Header h :
                    headers) {
                String value = h.getValue();
                String[] split = value.split("=");
                cookiesMap.put(split[0],split[1]);
            }
        }
    }


    private static BasicClientCookie createCookie(String key,String value) {
        BasicClientCookie cookie = new BasicClientCookie(key, value);
        cookie.setVersion(0);
        cookie.setDomain("/");   //设置范围
        cookie.setPath("/");
        return cookie;
    }


}
